//----------------------------------------------------------
    // 日志落地模块扩展：该模块是针对src/logsink.hpp文件中落地模板类的测试
        // 采用基于时间与文件大小的滚动文件落地，首先基于时间进行文件创建，当某一时间段内单个文件超过size时在该时间内创建多个文件
//----------------------------------------------------------

#include "../src/logsink.hpp"

namespace extendlog{
    // 扩展基于时间与文件大小的滚动文件
    enum
    {
        GAP_SECOND,
        GAP_MINUTE,
        GAP_HOUR,
        GAP_DAY,
        GAP_WEEK,
        GAP_MONTH,
    };
    class RollByTimeSizeSink : public ymbxlog::LogSink
    {
    public:
        RollByTimeSizeSink(const std::string &basename, size_t gap_time=GAP_MINUTE,size_t file_max_size=FILE_ONE_SINK_SIZE) : _basename(basename),_file_max_size(file_max_size)
        {
            ymbxlog::Util::File::CreatDir(ymbxlog::Util::File::GetDir(_basename));
            _gap_time = SetGapSize(gap_time);
        }
        virtual void Log(const std::string &str)
        {
            InitLog();
            _ofs.write(str.c_str(), str.size());
            if (!_ofs.good())
            {
                std::cout << "日志输出文件失败" << std::endl;
            }
            _file_cur_size+=str.size();
            _ofs.flush();
        }

    private:
        void InitLog()
        {
            size_t cur_time = ymbxlog::Util::Date::Now() / _gap_time;
            if (cur_time != _pre_time)
            {
                _ofs.close();
                _file_cnt=0;
                CreateNewFile(cur_time);
                _pre_time=cur_time;
            }
            if(cur_time == _pre_time && _file_cur_size >=_file_max_size){
                _ofs.close();
                _file_cnt++;
                CreateNewFile(cur_time);
            }
        }
        void CreateNewFile(time_t cur_time){
            std::string pathname=_basename+"_"+std::to_string(cur_time)+"_"+std::to_string(_file_cnt);
            _ofs.open(pathname,std::ios::binary | std::ios::app);
            if(!_ofs.is_open()){
                std::cout<<"基于时间与文件大小的滚动文件落地打开失败"<<std::endl;
                abort();
            }
            _file_cur_size=0;
        }
        size_t SetGapSize(size_t gap_size)
        {
            switch (gap_size)
            {
            case GAP_SECOND:
                return 1;
                break;
            case GAP_MINUTE:
                return 60;
                break;
            case GAP_HOUR:
                return 3600;
                break;
            case GAP_DAY:
                return 3600 * 24;
                break;
            case GAP_WEEK:
                return 3600 * 24 * 7;
                break;
            case GAP_MONTH:
                return 3600 * 24 * 30;
                break;
            default:
                return -1;
                break;
            }
        }

    private:
        std::string _basename;
        std::fstream _ofs;
        size_t _pre_time;
        size_t _gap_time;
        size_t _file_cur_size;
        size_t _file_max_size;
        size_t _file_cnt=0;
    };
}